package com.apes.fico.masterdata.gl.service;

import com.apes.fico.finance.respository.GLVoucherRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.fico.masterdata.gl.model.AccountingPeriod;
import com.apes.fico.masterdata.gl.model.AccountingPeriodItem;
import com.apes.fico.masterdata.gl.model.AccountingPeriodQuartItem;
import com.apes.fico.masterdata.gl.respository.AccountingPeriodRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName AccountingPeriodService
 * @Description TODO
 * @Author pengyb
 * @Date 2018/12/25 10:35
 * @Version 1.0
 **/
@Service("accountingPeriodService")
public class AccountingPeriodService extends DomainService {
    @Autowired
    private AccountingPeriodRepository accountingPeriodRepository;

    @Autowired
    private GLVoucherRepository glVoucherRepository;

    /**
     * 保存
     *
     * @param request
     * @return
     */
    public AccountingPeriod save(SimpleRequest request) {
        AccountingPeriod accountingPeriod = request.getO(AccountingPeriod.class);
        accountingPeriod.setCreateDate(new Date());
        return accountingPeriodRepository.saveAndFlush(accountingPeriod);
    }

    /**
     * 修改
     *
     * @param request
     * @return
     */
    public AccountingPeriod update(SimpleRequest request) {
        checkData(request);
        AccountingPeriod accountingPeriod = request.getO(AccountingPeriod.class);
        accountingPeriod.setUpdateDate(new Date());
        return accountingPeriodRepository.saveAndFlush(accountingPeriod);
    }

    /**
     * 删除
     *
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        checkData(request);
        AccountingPeriod accountingPeriod = request.getO(AccountingPeriod.class);
        checkGlvoucher(accountingPeriod);
        accountingPeriodRepository.delete(accountingPeriod.getId());
        return "删除成功";
    }

    /**
     * 检查是否已经有凭证产生
     */
    private void checkGlvoucher(AccountingPeriod accountingPeriod) {
        long icount = glVoucherRepository.count(JpaDsl.toCriteriaByEq("company.id", accountingPeriod.getCompany().getId(),
                "year", accountingPeriod.getYear()));
        if (icount > 0) {
            throw new RuntimeException("公司:" + accountingPeriod.getCompany().getName() + "已做账不允许删除");
        }
    }

    /**
     * 检查
     *
     * @param request
     */
    public void checkData(SimpleRequest request) {
        AccountingPeriod accountingPeriod = accountingPeriodRepository.findOne((String) request.get("id"));
        if (accountingPeriod == null) throw new RuntimeException("档案" + accountingPeriod.getId() + "不存在");
        if (accountingPeriod.getVersion() != (int) request.get("version"))
            throw new RuntimeException("档案" + accountingPeriod.getId() + "已更新或已删除");
    }


    /**
     * 带出会计月份
     *
     * @param request
     * @return
     */
    public List<AccountingPeriodItem> accountingDetails(SimpleRequest request) throws ParseException {
        String year = request.get("year");
        int yearInt = Integer.parseInt(year);
        String format = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        List<AccountingPeriodItem> accountingPeriodItems = new ArrayList<>();


        for (int i = 1; i <= 12; i++) {
            AccountingPeriodItem accountingPeriodItem = new AccountingPeriodItem();
            accountingPeriodItem.setPeriod_name(year + "年第" + i + "期");
            accountingPeriodItem.setPeriod_num(i);
            String month = i + "";
            if (i < 10) month = "0" + i;
            if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
                String fromDate = year + "-" + month + "-01";
                accountingPeriodItem.setFromDate(sdf.parse(fromDate));
                String thruDate = year + "-" + month + "-31";
                accountingPeriodItem.setThruDate(sdf.parse(thruDate));
            } else if (i == 4 || i == 6 || i == 9 || i == 11) {
                String fromDate = year + "-" + month + "-01";
                accountingPeriodItem.setFromDate(sdf.parse(fromDate));
                String thruDate = year + "-" + month + "-30";
                accountingPeriodItem.setThruDate(sdf.parse(thruDate));
            } else if (i == 2) {
                if ((yearInt % 4 == 0 && yearInt % 100 != 0) || yearInt % 400 == 0) {
                    String fromDate = year + "-" + month + "-01";
                    accountingPeriodItem.setFromDate(sdf.parse(fromDate));
                    String thruDate = year + "-" + month + "-29";
                    accountingPeriodItem.setThruDate(sdf.parse(thruDate));
                } else {
                    String fromDate = year + "-" + month + "-01";
                    accountingPeriodItem.setFromDate(sdf.parse(fromDate));
                    String thruDate = year + "-" + month + "-28";
                    accountingPeriodItem.setThruDate(sdf.parse(thruDate));
                }
            }
            accountingPeriodItem.setYearMonth(Integer.parseInt(year + month));
            accountingPeriodItem.setMonth(Integer.parseInt(month));

            accountingPeriodItems.add(accountingPeriodItem);
        }


        return accountingPeriodItems;
    }

    /**
     * 带出会计季度
     *
     * @param request
     * @return
     * @throws ParseException
     */
    public List<AccountingPeriodQuartItem> fiscalQuarter(SimpleRequest request) throws ParseException {
        String year = request.get("year");
        int yearInt = Integer.parseInt(year);
        String format = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        List<AccountingPeriodQuartItem> accountingPeriodQuartItems = new ArrayList<>();
        int month = 1;
        for (int i = 1; i <= 4; i++) {
            AccountingPeriodQuartItem accountingPeriodQuartItem = new AccountingPeriodQuartItem();
            accountingPeriodQuartItem.setPeriod_name(year + "年第" + i + "期");
            accountingPeriodQuartItem.setPeriod_num(i);
            accountingPeriodQuartItem.setFromMonth(month);
            month = month + 2;
            accountingPeriodQuartItem.setThruMonth(month);
            month++;
            accountingPeriodQuartItems.add(accountingPeriodQuartItem);
        }
        return accountingPeriodQuartItems;
    }

    /**
     * 会计期间
     *
     * @param request
     * @return
     */
    public Map fiscalPeriod(SimpleRequest request) {
        List<Map> maps = new ArrayList<>();
        List<Map> mapsYear = new ArrayList<>();

        if (!Objects.isNull(request.get("year"))) {
            if (!request.get("year").equals(0)) {
                AccountingPeriod accountingPeriod = accountingPeriodRepository.findByCompany_IdAndYear(request.get("company"), request.get("year"));
                accountingPeriod.getAccountingPeriodItems().forEach(accountingPeriodItem -> {
                    Map map = new HashMap();
                    map.put("id", accountingPeriodItem.getId());
                    map.put("period_name", accountingPeriodItem.getPeriod_name());
                    map.put("yearMonth", accountingPeriodItem.getYearMonth());
                    map.put("month", accountingPeriodItem.getMonth());
                    maps.add(map);

                });
            } else {
                accountingPeriodRepository.findByCompany_Id(request.get("company")).forEach(accountingPeriod -> {
                    Map mapYear = new HashMap();
                    mapYear.put("year", accountingPeriod.getYear());
                    mapsYear.add(mapYear);
                });
            }
        }
        Map map = new HashMap();
        map.put("period", maps);
        map.put("year", mapsYear);

        List<Map> mapsMonth = new ArrayList<>();
        maps.forEach(mp -> {
            Map m = new HashMap();
            m.put("month", mp.get("month"));
            mapsMonth.add(m);
        });
        map.put("month", mapsMonth);
        return map;
    }

    /**
     * 会计期间
     *
     * @param request
     * @return
     */
    public List<Map> fiscalPerPeriodOutstanding(SimpleRequest request) {
        List<Map> maps = accountingPeriodRepository.finAccountingPeriodItems("1001");
        return maps;
    }
}
